package com.zbl.zblproject.erp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Preconditions;
import com.zbl.zblproject.core.entity.AdminUser;
import com.zbl.zblproject.core.mapper.BrandMapper;
import com.zbl.zblproject.core.mapper.SmallUnitMapper;
import com.zbl.zblproject.core.mapper.SupplierMapper;
import com.zbl.zblproject.erp.entity.*;
import com.zbl.zblproject.erp.mapper.*;
import com.zbl.zblproject.erp.service.ErpAllotService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author youlanqiang
 * @version 1.0
 * @date 2018/10/24
 */
@Service
public class ErpAllotServiceImpl implements ErpAllotService {


    @Autowired
    private BrandMapper erpBrandMapper;

    @Autowired
    private ErpCategoryMapper erpCategoryMapper;

    @Autowired
    private SupplierMapper erpSupplierMapper;

    @Autowired
    private ErpWarehouseItemMapper warehouseItemMapper;

    @Autowired
    private ErpWarehouseMapper warehouseMapper;

    @Autowired
    private ErpGoodMapper goodMapper;

    @Autowired
    private ErpAllotOrderMapper allotOrderMapper;

    @Autowired
    private ErpAllotOrderItemMapper allotOrderItemMapper;

    @Autowired
    private SmallUnitMapper smallUnitMapper;



    @Override
    @Transactional
    public boolean rollback(int id) {
        ErpAllotOrder order = allotOrderMapper.selectById(id);
        if(order == null || order.getStatus() != 1){
            throw new RuntimeException("订单不存在,或者订单状态无效");
        }
        order.setStatus(1);
        return allotOrderMapper.updateById(order) == 1;
    }

    @Override
    public IPage<ErpAllotOrder> page(String search, int current, int size) {
        Page<ErpAllotOrder> page = new Page<>(current, size);
        QueryWrapper<ErpAllotOrder> wrapper = new QueryWrapper<>();
        wrapper.apply(search).orderByDesc("id");
        return allotOrderMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional
    public ErpAllotOrder createOrderByStatus(String orderSn, int status, AdminUser user, List<ErpAllotOrderItem> orderItems) {
        ErpAllotOrder order = selectByOrderSn(orderSn);
        boolean needUp = false;
        if(orderItems.isEmpty()){
            throw new RuntimeException("订单调拨不能为空");
        }
        if(status != 0 && status != 1){
            throw new RuntimeException("订单状态异常");
        }
        if(order == null){
            //新建订单
            order = new ErpAllotOrder();
            needUp = true;
        }
        order.setAllotSn(orderSn);
        order.setOperator(user.getUserName());
        order.setStatus(status);
        order.setCreateTime(LocalDateTime.now());
        if(needUp){
            allotOrderMapper.insert(order);
        }else{
            allotOrderMapper.updateById(order);
        }
        final int orderId = order.getId();
        reviewOrder(order, orderItems, (x)->{
            x.setOrderId(orderId);
            allotOrderItemMapper.insert(x);
        });
        return order;

    }

    @Override
    public List<ErpAllotOrderItem> orderItemByOrderSn(String orderSn) {
        ErpAllotOrder order = selectByOrderSn(orderSn);
        Preconditions.checkNotNull(order, "订单不存在");
        QueryWrapper<ErpAllotOrderItem> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", order.getId());
        List<ErpAllotOrderItem> items = allotOrderItemMapper.selectList(wrapper);
        items.forEach(x->{
            ErpGoods goods = goodMapper.selectById(x.getGoodsId());
            goods.setErpBrand(erpBrandMapper.selectById(goods.getBrandId()));
            goods.setErpCategory(erpCategoryMapper.selectById(goods.getCatId()));
            goods.setErpSupplier(erpSupplierMapper.selectById(goods.getSuppliersId()));
            goods.setSmallUnitName(smallUnitMapper.selectById(goods.getSmallunitId()).getName());
            x.setGoods(goods);
            x.setWarehouseFrom(warehouseMapper.selectById(x.getFromWh()));
            x.setWarehouseTo(warehouseMapper.selectById(x.getToWh()));
        });
        return items;
    }

    @Override
    @Transactional
    public boolean updateOrder(String orderSn) {
        ErpAllotOrder order = selectByOrderSn(orderSn);
        if(order == null) {
            return false;
        }
        List<ErpAllotOrderItem> items = orderItemByOrderSn(orderSn);
        if(order.getStatus() == 0){
            //订单由草稿 --> 复合中
            order.setStatus(1);
            return allotOrderMapper.updateById(order) == 1;
        }
        if(order.getStatus() == 1){
            //订单由审核中 --> 审核成功
            order.setStatus(2);
            items.forEach(x->{
                //from_whid 转移到 to_whid中
                transfer(x);
            });
            return allotOrderMapper.updateById(order) == 1;
        }
        return false;

    }

    @Override
    @Transactional
    public boolean deleteOrderById(int id) {
        ErpAllotOrder order = allotOrderMapper.selectById(id);
        if(order == null){
            return false;
        }
        if(order.getStatus() != 0 && order.getStatus() != 1){
            return false;
        }
        QueryWrapper<ErpAllotOrderItem> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", id);
        allotOrderItemMapper.delete(wrapper);
        return 1 == allotOrderMapper.deleteById(id);
    }

    private void  transfer(ErpAllotOrderItem item){
        ErpWarehouse warehouseFrom = warehouseMapper.selectById(item.getFromWh());
        Preconditions.checkNotNull(warehouseFrom, "未发现该仓库");
        ErpWarehouse warehouseTo = warehouseMapper.selectById(item.getToWh());
        Preconditions.checkNotNull(warehouseTo, "未发现该仓库");

        ErpWarehouseItem goodsFrom = warehouseItemMapper.selectItemByGoodsIdAndWhId(item.getGoodsId(), item.getFromWh());
        if(goodsFrom == null || goodsFrom.getStock() == 0 || goodsFrom.getStock() < item.getNumber()){
            throw new RuntimeException("仓库库存不足!");
        }else{
            goodsFrom.setStock(goodsFrom.getStock() - item.getNumber());
            warehouseItemMapper.updateById(goodsFrom);
        }
        ErpWarehouseItem goodsTo = warehouseItemMapper.selectItemByGoodsIdAndWhId(item.getGoodsId(), item.getToWh());
        if(goodsTo == null){
            goodsTo = new ErpWarehouseItem();
            goodsTo.setWhId(item.getToWh());
            goodsTo.setGoodsId(item.getGoodsId());
            goodsTo.setStock(item.getNumber());
            warehouseItemMapper.insert(goodsTo);
        }else{
            goodsTo.setStock(goodsTo.getStock() + item.getNumber());
            warehouseItemMapper.updateById(goodsTo);
        }


    }


    private ErpAllotOrder selectByOrderSn(String orderSn){
        QueryWrapper<ErpAllotOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("allot_sn", orderSn);
        return allotOrderMapper.selectOne(wrapper);
    }


    /**
     * 订单项目重置
     * @param order
     * @param items
     */
    private void reviewOrder(final ErpAllotOrder order, List<ErpAllotOrderItem> items, Consumer<ErpAllotOrderItem> consumer){
        //删除该订单下的所有原始数据
        QueryWrapper<ErpAllotOrderItem> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", order.getId());
        allotOrderItemMapper.delete(wrapper);
        items.forEach(consumer);
    }
}
